//
//  FFNetworkCache.m
//  FFNetworkCache
//
//  Created by Wonder Chang on 16/3/21.
//  Copyright © 2016年 isoftstone. All rights reserved.
//

#import "FFNetworkCache.h"
#import "FFNetCacheConfig.h"
#import "FFNetCacheDao.h"
#import "FFNetCacheVO.h"

@implementation FFNetworkCache


static FFNetworkCache *instance = nil;


- (void)operation
{
    // do something
    NSLog(@"Singleton");
}

+ (FFNetworkCache *)sharedNetworkCache
{
#if ! __has_feature(objc_arc)
    
    if (instance == nil)
    {
        instance = [[self alloc] init];
    }
    return instance;
#else
    static dispatch_once_t pred = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init]; // or some other init method
    });
    return _sharedObject;
#endif
    
}

#if ! __has_feature(objc_arc)

+ (id) allocWithZone:(NSZone *)zone
{
    return IMF_RETAIN([self sharedManager]);
}


- (id) copyWithZone:(NSZone*)zone
{
    return self;
}

- (id) retain
{
    return self;
}

- (NSUInteger)retainCount
{
    return NSUIntegerMax; // denotes an object that cannot be released
}

- (oneway void) release
{
    // do nothing
}

- (id) autorelease
{
    return self;
}
#endif


- (void)registerSDKWithAppKey:(NSString *)anAppKey {
    
}


- (void)setCacheConfig:(NSDictionary * (^)())cacheConfigBlock cacheMaxNumber:(long (^)())cacheMaxNumberBlock {
    NSDictionary *d = cacheConfigBlock();
    long maxNum = cacheMaxNumberBlock();
    
    [FFNetCacheConfig setCacheConfig:d cacheMaxNumber:maxNum];
}


- (NSString *)getRespWithURL:(NSString *)url requestBody:(NSString *)req {
    
    if([FFNetCacheConfig getCacheConfigByURL:url] == 0l){
        NSLog(@"url = %@ 配置不需要缓存，直接return", url);
        return nil;
    }
    
    FFNetCacheDao *dao = [[FFNetCacheDao alloc] init];
    FFNetCacheVO *entity = [[FFNetCacheVO alloc] init];
    entity.url = url;
    entity.req = req;
    
    NSArray *cachedArray = [dao queryWithEntity:entity];
    if ([cachedArray count]>0) {
        
        FFNetCacheVO *cache = [cachedArray objectAtIndex:0];
        NSLog(@"查询到缓存: %@", [cache toString]);

        // 在有效时间内，才采用
        long long currentTimeMillis = [[NSDate date] timeIntervalSince1970]*1000;
        if (currentTimeMillis - cache.respTime < [FFNetCacheConfig getCacheConfigByURL:url]) {
            return cache.resp;
        }else{
            NSLog(@"缓存已过期， 不再使用");
        }
    }
    
    
    return nil;
}



- (void)putCacheWithURL:(NSString *)url
            requestBody:(NSString *)req
            requestTime:(long long)reqTime
               response:(NSString *)resp
           responseTime:(long long)respTime {
    if([FFNetCacheConfig getCacheConfigByURL:url] == 0l){
        NSLog(@"url = %@ 配置不需要缓存，直接return", url);
        return;
    }
    
    FFNetCacheVO *entity = [[FFNetCacheVO alloc] init];
    entity.url = url;
    entity.req = req;
    entity.reqTime = reqTime;
    entity.resp = resp;
    entity.respTime = respTime;
    
    FFNetCacheDao *dao = [[FFNetCacheDao alloc] init];
    
    NSArray *cachedArray = [dao queryWithEntity:entity];
    
    if ([cachedArray count]>0) {
        entity._id = [(FFNetCacheVO *)cachedArray[0] _id];
        NSLog(@"已经缓存过，做更新操作: %@", [entity toString]);
        [dao updateWithEntity:entity];
    }
    else {
        NSLog(@"还未缓存过，做插入操作: %@", [entity toString]);
        [dao insertWithEntity:entity];
    }
    
    
    // 清除超出数量的缓存
    cachedArray = [dao queryWithEntity:entity];
    if ([cachedArray count]>FFNetCacheConfig.cacheMaxNum) {
        NSLog(@"缓存条数超过最大允许数：%ld，需要做删除操作",FFNetCacheConfig.cacheMaxNum);
        
        for (long i=FFNetCacheConfig.cacheMaxNum; i<[cachedArray count]; i++) {
            FFNetCacheVO *obj = [cachedArray objectAtIndex:i];
            [dao deleteWithEntity:obj];
        }
    }
    
}


- (BOOL)deleteCacheWithURL:(NSString *)url requestBody:(NSString *)req {
    
    FFNetCacheVO *entity = [[FFNetCacheVO alloc] init];
    entity.url = url;
    entity.req = req;
    
    FFNetCacheDao *dao = [[FFNetCacheDao alloc] init];

    return [dao deleteWithEntity:entity];
}

- (BOOL)deleteAllCache{
    FFNetCacheDao *dao = [[FFNetCacheDao alloc] init];

    return [dao deleteWithEntity:nil];
}

    


@end
